package org.arnetminer.personalized.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.arnetminer.personalized.dao.StatusDAO;
import org.arnetminer.personalized.util.Global;
import org.arnetminer.personalized.vo.Comment;
import org.arnetminer.personalized.vo.Event;
import org.arnetminer.personalized.vo.EventType;
import org.arnetminer.personalized.vo.Notification;
import org.arnetminer.personalized.vo.Status;
import org.arnetminer.personalized.vo.User;

public class StatusServiceImpl implements StatusService {
	private StatusDAO statusDAO;

	public StatusDAO getStatusDAO() {
		return statusDAO;
	}

	public void setStatusDAO(StatusDAO statusDAO) {
		this.statusDAO = statusDAO;
	}

	private EventService eventService;

	public EventService getEventService() {
		return eventService;
	}

	public void setEventService(EventService eventService) {
		this.eventService = eventService;
	}

	public boolean save(Status status) {
		
		try {
			statusDAO.save(status);

			Event event = new Event();
			event.setPostDate(status.getPostDate());
			event.setSubId(status.getUser().getId());
			event.setEventId(status.getId());
			EventType type = eventService.getEventType(Global.STATUSEVENT);
			event.setType(type);
			eventService.save(event);

		} catch (Exception ex) {
			ex.printStackTrace();
			return false;
		}
		return true;
	}

	public List getUserStatus(User user, int start, int max) {
		List<String> properties = new ArrayList();
		List values = new ArrayList();
		properties.add("user");
		values.add(user);

		List status = statusDAO
				.findByProperties(properties, values, start, max);
		return status;
	}

	public boolean delete(long id, User user) {

		List<String> properties = new ArrayList();
		List values = new ArrayList();
		properties.add("user");
		values.add(user);

		properties.add("id");
		values.add(id);

		List<Status> status = statusDAO.findByProperties(properties, values, 0,
				1);

		if (status == null || status.size() == 0) {
			return false;
		}
		try {
			statusDAO.delete(status.get(0));
		} catch (Exception ex) {
			return false;
		}
		return true;
	}

	public Status getStatus(long id) {
		return statusDAO.findById(id);
	}

	public boolean saveComment(Comment comment) {
		try {
			statusDAO.saveComment(comment);
			Status status = comment.getStatus();
			List<Comment> comments = this.getStatusComment(status);
			
			Map<Long, User> users = new HashMap<Long, User>();
			User user = status.getUser();
			users.put(user.getId(), user);
			for (int i = 0; i < comments.size(); i++) {
				Comment excomment = comments.get(i);
				user = excomment.getUser();
				if (!users.containsKey(user.getId()))
					users.put(user.getId(), user);
			}
			
			EventType eventType = eventService.getEventType(Global.STATUSEVENT);
			
			List<String> properties = new ArrayList<String>();
			List values = new ArrayList();
			properties.add("type");
			values.add(eventType);
			properties.add("eventId");
			values.add(status.getId());
			
			List<Event> events = eventService.getEventsByProperties(properties, values, 0, 1);
			
			if (events != null && events.size() > 0) {
				Event event = events.get(0);
				Collection<User> userList = users.values();
				Iterator<User> userIt = userList.iterator();
				while (userIt.hasNext()) {
					user = userIt.next();
					properties = new ArrayList<String>();
					values = new ArrayList();
					properties.add("event");
					values.add(event);
					properties.add("notifiee");
					values.add(user);
					List<Notification> notis = eventService.getNotificationsByProperties(properties, values, 0, 1);
					
					if (notis == null || notis.size() == 0) {
						Notification noti = new Notification();
						noti.setEvent(event);
						noti.setNotifiee(user);
						eventService.notify(noti);
					}
					
				}
				
			}
			
		} catch (Exception ex) {
			ex.printStackTrace();
			return false;
		}
		return true;
	}

	public List getStatusComment(Status status, int start, int max) {
		List<String> properties = new ArrayList();
		List values = new ArrayList();
		properties.add("status");
		values.add(status);

		List comments = statusDAO.findCommentByProperties(properties, values,
				start, max);
		return comments;
	}
	
	public List getStatusComment(Status status) {
		List<String> properties = new ArrayList();
		List values = new ArrayList();
		properties.add("status");
		values.add(status);

		List comments = statusDAO.findCommentByProperties(properties, values);
		return comments;
	}

	public boolean deleteComment(long id, User user) {

		List<String> properties = new ArrayList();
		List values = new ArrayList();
		properties.add("user");
		values.add(user);

		properties.add("id");
		values.add(id);

		List status = statusDAO.findCommentByProperties(properties, values, 0,
				1);

		if (status == null || status.size() == 0) {
			return false;
		}
		return statusDAO.deleteComment(id);
	}

}
